package com.yupi.springbootinit.utils;

import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class AuthUtils {
    public static String genAuthUrl(String apiKey, String apiSecret, String host, String path) throws Exception {
        if (StringUtils.isAnyBlank(apiKey, apiSecret, host, path)) {
            throw new InvalidParameterException("genAuthUrl 参数不能为空!");
        }
        try {
            String date = getRFC1123Date();
            return generateAuthorization(date, host, path, apiSecret, apiKey);
        } catch (Exception e) {
            throw e;
        }
    }

    private static byte[] hmacSHA256Hex(String data, String secret) {
        // 转换密钥和原始数据为字节数组
        byte[] secretBytes = secret.getBytes(StandardCharsets.UTF_8);
        byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);

        // 初始化一个Mac实例
        Mac sha256_HMAC = null;
        try {
            sha256_HMAC = Mac.getInstance("HmacSHA256");

        // 初始化Mac实例，使用提供的密钥
        SecretKeySpec secret_key = new SecretKeySpec(secretBytes,"HmacSHA256");
        sha256_HMAC.init(secret_key);

        // 计算HMAC
            return sha256_HMAC.doFinal(dataBytes);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"hmacSHA256Hex 失败");
        }
    }

    private static String generateAuthorization(String date, String host, String path, String apiSecret, String apiKey) {
        String tmp = "host: " + host + "\n";
        tmp += "date: " + date + "\n";
        tmp += "GET " + path + " HTTP/1.1";
        byte[] tmp_sha = hmacSHA256Hex(tmp, apiSecret);
        String signature = Base64.getEncoder().encodeToString(tmp_sha);
        String authorization_origin = String.format("api_key='%s', algorithm='hmac-sha256', headers='host date request-line', signature='%s'", apiKey, signature);
        String authorization = Base64.getEncoder().encodeToString(authorization_origin.getBytes(StandardCharsets.UTF_8));
        return "wss://"+host + path +"?authorization=" + authorization + "&date=" + date + "&host=" + host;
    }

    private static String getRFC1123Date() {
        ZonedDateTime now = ZonedDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME;
        formatter.withLocale(Locale.US);
        return now.format(formatter);
    }
}

